import json
import uuid

from django.core.cache import cache, caches
from django.core.exceptions import ObjectDoesNotExist
import hashlib
from django import views
from django.http import HttpRequest
from django.http.response import JsonResponse, HttpResponseBadRequest, HttpResponse
from django.shortcuts import render
from django.utils.decorators import method_decorator
from django.views.decorators.cache import cache_page
# from django_filters.rest_framework import DjangoFilterBackend
from rest_framework.exceptions import ValidationError
from rest_framework.filters import SearchFilter
from rest_framework.parsers import MultiPartParser, FormParser, JSONParser
from rest_framework.permissions import BasePermission
from rest_framework.renderers import JSONRenderer, BrowsableAPIRenderer, TemplateHTMLRenderer
from rest_framework.request import Request
from rest_framework.response import Response
from rest_framework.views import APIView
from rest_framework.viewsets import ModelViewSet

from product.models import ProductCategory, User, Product
from rest_framework import mixins, generics, permissions
# Create your views here.
from product.paginations import MyPaginationClass
from product.parsers import P1902Parser
from product.permissions import ProductPermissionAny
from product.renderers import P1902Renderer
from product.serializers import ProductCategorySerializer, UserSerializer, ProductSerializer
from rest_framework import pagination
import logging

logger = logging.getLogger("django")


# class ProductCategoryView(views.View):
#     def get(self, request, pk=None, *args, **kwargs):
#         if pk is None:
#             categories = ProductCategory.objects.filter(parent=None)
#             objs = ProductCategorySerializer(instance=categories, many=True)
#             return JsonResponse(json.loads(json.dumps(objs.data), strict=False), safe=False)
#         else:
#             try:
#                 category = ProductCategory.objects.get(pk=pk)
#                 pm = ProductCategorySerializer(instance=category)
#                 return JsonResponse(pm.data)
#             except ObjectDoesNotExist:
#                 return HttpResponseBadRequest()
#
#     def post(self, request, pk=None, *args, **kwargs):
#         if pk is None:
#             m = ProductCategorySerializer(data={"name": request.POST['name'],
#                                                 "title": request.POST['title']})
#             if not m.is_valid():
#                 return HttpResponseBadRequest()
#             c = m.save()
#             return JsonResponse(m.data)
#
#         return HttpResponseBadRequest()

# class ProductCategoryView(generics.ListAPIView,
#                           generics.CreateAPIView,
#                           generics.RetrieveAPIView,
#                           generics.UpdateAPIView,
#                           generics.DestroyAPIView):
#     permission_classes = (ProductPermissionAny,)
#     serializer_class = ProductCategorySerializer
#     queryset = ProductCategory.objects.filter(parent=None)


# parent = self.request.query_params.get("parent", None)
# return ProductCategory.objects.filter(parent__pk=parent)


# class UserView(views.View):
#     def post(self, request, *args, **kwargs):
#         serializer = UserSerializer(data={
#             "telephone": request.POST.get("telephone", ""),
#             "nick_name": request.POST.get("nick_name", ""),
#             "password": request.POST.get("password", "")
#         })
#
#         try:
#             serializer.is_valid(raise_exception=True)
#         except ValidationError as e:
#             return HttpResponseBadRequest(str(e))
#         else:
#             salt = uuid.uuid4().hex
#             password = hashlib.md5((serializer.validated_data['password'] + salt).encode("utf-8")).hexdigest()
#             model = serializer.save(password=password, salt=salt)
#             # model.password = password
#             # model.salt = salt
#             # model.save(force_update=True)
#             return HttpResponse("SUCCESS")

# class UserView(APIView):
#     parser_classes = (JSONParser, FormParser, MultiPartParser, P1902Parser)
#     renderer_classes = (P1902Renderer, JSONRenderer, BrowsableAPIRenderer)
#
#     def get(self, request, pk=None, format=None):
#         assert isinstance(request, Request)
#         if not pk:
#             users = User.objects.all()
#             user_set = UserSerializer(instance=users, many=True)
#             return Response(user_set.data)
#         else:
#             user = User.objects.get(pk=pk)
#             return Response(UserSerializer(instance=user).data)
#
#     def post(self, request, format=None):
#         from rest_framework.request import Request
#         assert isinstance(request, Request)
#         serializer = UserSerializer(data=request.data)
#         try:
#             serializer.is_valid(raise_exception=True)
#         except ValidationError as e:
#             return HttpResponseBadRequest(str(e))
#         else:
#             salt = uuid.uuid4().hex
#             password = hashlib.md5((serializer.validated_data['password'] + salt).encode("utf-8")).hexdigest()
#             model = serializer.save(password=password, salt=salt)
#             return Response(UserSerializer(instance=model).data)

# 使用Mixins类
# class UserView(mixins.ListModelMixin,
#                mixins.CreateModelMixin,
#                mixins.RetrieveModelMixin,
#                mixins.UpdateModelMixin,
#                mixins.DestroyModelMixin,
#                generics.GenericAPIView):
#
#     queryset = User.objects.all()
#     serializer_class = UserSerializer
#
#     def get(self, request, pk=None, *args, **kwargs):
#         if pk is None:
#             return self.list(request, *args, **kwargs)
#         else:
#             return self.retrieve(request, *args, **kwargs)
#
#     def post(self, request, *args, **kwargs):
#         return self.create(request, *args, **kwargs)
#
#     def put(self, request, *args, **kwargs):
#         return self.update(request, *args, **kwargs)
#
#     def delete(self, request, *args, **kwargs):
#         return self.destroy(request, *args, **kwargs)
#
#     def perform_create(self, serializer):
#         salt = uuid.uuid4().hex
#         password = hashlib.md5((serializer.validated_data['password'] + salt).encode("utf-8")).hexdigest()
#         serializer.save(password=password, salt=salt)

# 使用Generic class-based views,
# 创建列表视图
class UserListView(generics.ListAPIView,
                   generics.CreateAPIView):
    queryset = User.objects.all()
    serializer_class = UserSerializer

    def perform_create(self, serializer):
        salt = uuid.uuid4().hex
        password = hashlib.md5((serializer.validated_data['password'] + salt).encode("utf-8")).hexdigest()
        serializer.save(password=password, salt=salt)


# 创建详情视图
class UserDetailView(generics.RetrieveAPIView,
                     generics.UpdateAPIView,
                     generics.DestroyAPIView):
    queryset = User.objects.all()
    serializer_class = UserSerializer


class ProductView(generics.ListAPIView,
                  generics.CreateAPIView,
                  generics.RetrieveAPIView,
                  generics.UpdateAPIView,
                  generics.DestroyAPIView):
    serializer_class = ProductSerializer
    queryset = Product.objects.all()
    permission_classes = (ProductPermissionAny,)


# 将列表视图与详情视图绑定
class UserView(ModelViewSet):
    queryset = User.objects.all()
    serializer_class = UserSerializer
    # permission_classes = (permissions.IsAuthenticatedOrReadOnly, ProductPermissionAny)
    pagination_class = MyPaginationClass
    # filter_backends = (DjangoFilterBackend,)
    # search_fields = ("$telephone", "password")
    filterset_fields = ("nick_name",)

    # def get_queryset(self):
    #     self.queryset = User.objects.all()
    #     for param_name in self.request.query_params:
    #         param_value = self.request.query_params.get(param_name)
    #         self.queryset = self.queryset.filter(**{param_name: param_value})
    #     # self.queryset = self.queryset.filter(title=sdfsdfsdf,parent=)
    #     return self.queryset

    # def get(self, request, pk=None, *args, **kwargs):
    #     if pk is None:
    #         return generics.ListAPIView.get(self, request, *args, **kwargs)
    #         # super(generics.ListAPIView).get(request, *args, **kwargs)
    #     else:
    #         return generics.RetrieveAPIView.get(self, request, *args, **kwargs)
    # super(generics.RetrieveAPIView).get(request, *args, **kwargs)

    def perform_create(self, serializer):
        salt = uuid.uuid4().hex
        password = hashlib.md5((serializer.validated_data['password'] + salt).encode("utf-8")).hexdigest()
        serializer.save(password=password, salt=salt)


class ProductCategoryView(ModelViewSet):
    permission_classes = (ProductPermissionAny,)
    serializer_class = ProductCategorySerializer
    queryset = ProductCategory.objects.filter(parent=None)

    @method_decorator(cache_page(60 * 60))
    def get(self, request, *args, **kwargs):
        logger.info("Get method to request product")
        return super().get(request, *args, **kwargs)


def test(request):
    logger.info(request.GET['data'])
    return HttpResponse("OK")


# class UserView(ModelViewSet):
#     pass

# user_list_view = UserView.as_view({
#     'get': 'list',
#     'post': 'create'
# })
#
# user_detail_view = UserView.as_view({
#     "get": "retrieve"
# })

# cache the entire page
@cache_page(60 * 60)
def my_view(request):
    return render(request, "user.html", {})


def other_view(request):
    cache.set("other_view", "sfdsdfsdfsdfsdf")
    return HttpResponse("hello")


# class MyView(views.View):
#     @method_decorator(cache_page())
#     def get(self, request):
#         pas
